package shuai7boy.vip.transformer.server.impl;

import java.awt.Dimension;
import java.io.IOException;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.log4j.Logger;

import shuai7boy.vip.transformer.model.dim.base.BaseDimension;
import shuai7boy.vip.transformer.model.dim.base.BrowserDimension;
import shuai7boy.vip.transformer.model.dim.base.DateDimension;
import shuai7boy.vip.transformer.model.dim.base.PlatformDimension;
import shuai7boy.vip.transformer.server.IDimensionConverter;

public class DimensionConverImpl implements IDimensionConverter {
	private static final Logger logger = Logger.getLogger(Dimension.class);
	private static final String DRIVER = "com.mysql.jdbc.Driver";
	private static final String URL = "jdbc:mysql://tuge1:3306/result_db";
	private static final String USER = "root";
	private static final String PASSWORD = "123456";
	private Map<String, Integer> cache = new LinkedHashMap<String, Integer>() {
		private static final long serialVersionUID = 8894507016522723685L;

		@Override
		protected boolean removeEldestEntry(Map.Entry<String, Integer> eldest) {
			return this.size() > 5000;
		};
	};

	Map<String, Integer> cc = new LinkedHashMap<String, Integer>() {

	};
	static {
		try {
			Class.forName(DRIVER);
		} catch (ClassNotFoundException ex) {
			ex.printStackTrace();
		}

	}

	// 查询维度信息，将不存在的插入数据库
	// 定义url，user，password

	@Override
	public int getDimensionIdByValue(BaseDimension dimension) throws IOException {
		// TODO Auto-generated method stub
		String cacheKey = buildCacheKey(dimension);
		System.out.println("————————维度的cache key +" + cacheKey);
		if (this.cache.containsKey(cacheKey)) {
			return this.cache.get(cacheKey);
		}
		Connection conn = null;
		try {
			// 1. 查看数据库中是否有对应的值，有则返回
			// 2. 如果第一步中，没有值；先插入我们dimension数据， 获取id

			// 不包含的化，调用开始执行插入语句
			String[] sql = {};
			if (dimension instanceof DateDimension) {
				sql = this.buildDateSql();
			} else if (dimension instanceof PlatformDimension) {
				sql = this.buildPlatformSql();
			} else if (dimension instanceof BrowserDimension) {
				sql = this.buildBrowserSql();
			} else {
				throw new IOException("不支持此dimensionid的获取:" + dimension.getClass());
			}
			conn = this.getConnection(); // 获取连接
			int id = 0;
			synchronized (this) {
				id = this.executeSql(conn, cacheKey, sql, dimension);
				this.cache.put(cacheKey, id);
			}
			return id;

		} catch (SQLException ex) {
			ex.printStackTrace();
		}

		return 0;
	}

	/**
	 * 创建date dimension相关sql
	 * 
	 * @return
	 */
	private String[] buildDateSql() {
		String querySql = "SELECT `id` FROM `dimension_date` WHERE `year` = ? AND `season` = ? AND `month` = ? AND `week` = ? AND `day` = ? AND `type` = ? AND `calendar` = ?";
		String insertSql = "INSERT INTO `dimension_date`(`year`, `season`, `month`, `week`, `day`, `type`, `calendar`) VALUES(?, ?, ?, ?, ?, ?, ?)";
		return new String[] { querySql, insertSql };
	}

	/**
	 * 创建polatform dimension相关sql
	 * 
	 * @return
	 */
	private String[] buildPlatformSql() {
		String querySql = "SELECT `id` FROM `dimension_platform` WHERE `platform_name` = ?";
		String insertSql = "INSERT INTO `dimension_platform`(`platform_name`) VALUES(?)";
		return new String[] { querySql, insertSql };
	}

	/**
	 * 创建browser dimension相关sql
	 * 
	 * @return
	 */
	private String[] buildBrowserSql() {
		String querySql = "SELECT `id` FROM `dimension_browser` WHERE `browser_name` = ? AND `browser_version` = ?";
		String insertSql = "INSERT INTO `dimension_browser`(`browser_name`, `browser_version`) VALUES(?, ?)";
		return new String[] { querySql, insertSql };
	}

	public Connection getConnection() throws SQLException {
		try {
			return DriverManager.getConnection(URL, USER, PASSWORD);
		} catch (SQLException ex) {
			ex.printStackTrace();
		}
		return null;
	}

	
	@SuppressWarnings("")
	private int executeSql(Connection conn, String cacheKey, String[] sqls, BaseDimension dimension)
			throws SQLException {
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		try {
			pstmt = conn.prepareStatement(sqls[0]); // 创建查询sql的pstmt对象
			// 设置参数
			this.setArgs(pstmt, dimension);
			rs = pstmt.executeQuery();
			if (rs.next()) {
				return rs.getInt(1);
			}
			// 代码运行到这儿，表示该dimension在数据库中不存储，进行插入
			pstmt = conn.prepareStatement(sqls[1], java.sql.Statement.RETURN_GENERATED_KEYS);
			// 设置参数
			this.setArgs(pstmt, dimension);
			pstmt.executeUpdate();
			rs = pstmt.getGeneratedKeys();
			if (rs.next()) {
				return rs.getInt(1);// 获取返回值
			}

		} finally {
			if (rs != null) {
				try {
					rs.close();
				} catch (Throwable e) {

				}
			}
			if (conn != null) {
				try {
					conn.close();
				} catch (Throwable e) {

				}
			}
		}
		throw new RuntimeException("从数据库获取id失败");
	}

	/**
	 * 设置参数
	 * 
	 * @param pstmt
	 * @param dimension
	 * @throws SQLException
	 */
	private void setArgs(PreparedStatement pstmt, BaseDimension dimension) throws SQLException {
		int i = 0;
		if (pstmt instanceof DateDimension) {
			DateDimension date = (DateDimension) dimension;
			pstmt.setInt(++i, date.getYear());
			pstmt.setInt(++i, date.getSeason());
			pstmt.setInt(++i, date.getMonth());
			pstmt.setInt(++i, date.getWeek());
			pstmt.setInt(++i, date.getDay());
			pstmt.setString(++i, date.getType());
			pstmt.setDate(++i, new Date(date.getCalendar().getTime()));
		} else if (dimension instanceof PlatformDimension) {
			PlatformDimension platform = (PlatformDimension) dimension;
			pstmt.setString(++i, platform.getPlatformName());
		} else if (dimension instanceof BrowserDimension) {
			BrowserDimension browser = (BrowserDimension) dimension;
			pstmt.setString(++i, browser.getBrowserName());
			pstmt.setString(++i, browser.getBrowserVersion());
		}

	}

	/**
	 * 创建cachekey
	 * 
	 * @param dimension
	 * @return
	 */
	private static String buildCacheKey(BaseDimension dimension) {
		StringBuilder sb = new StringBuilder();
		if (dimension instanceof DateDimension) {
			sb.append("date_dimension");
			DateDimension date = (DateDimension) dimension;
			sb.append(date.getYear()).append(date.getSeason()).append(date.getMonth());
			sb.append(date.getWeek()).append(date.getDay()).append(date.getType());
		} else if (dimension instanceof PlatformDimension) {
			sb.append("platform_dimension");
			PlatformDimension platform = (PlatformDimension) dimension;
			sb.append(platform.getPlatformName());
		} else if (dimension instanceof BrowserDimension) {
			sb.append("browser_dimension");
			BrowserDimension browser = (BrowserDimension) dimension;
			sb.append(browser.getBrowserName()).append(browser.getBrowserVersion());
		}

		if (sb.length() == 0) {
			throw new RuntimeException("无法创建指定dimension的cachekey：" + dimension.getClass());
		}
		return sb.toString();
	}

}
